www.gusucode.com > Non-photorealistic Camera工具箱源码matlab程序 > Non-photorealistic Camera/NPC.m
function NPC(up_img,right_img,down_img,left_img,dest_folder) %NPC: implementation of Non-photorealistic Camera 04. The function finds %the depth edges of foreground object that was captured using 4 different %flashes: up, right, down, and left respectively. The 4 images should be %captured using a tripod setup. The result is a non-photorealistic %image that is generated based on the extracted depth edges. The output %images are saved in the "dest_folder". %Citation: %Raskar, Ramesh, et al. "Non-photorealistic camera: depth edge detection %and stylized rendering using multi-flash imaging." ACM transactions on %graphics (TOG). Vol. 23. No. 3. ACM, 2004. %Input: % -up_img: the up image (captured using the up flash) % -right_img: the right image % -down_img: the down image % -left_img: the left image % -dest_folder: the destination folder that is used to save the output % images %Usage: %NPC(u,r,d,l,'save'); %Author: Mahmoud Afifi - York University %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% if exist(dest_folder,'dir')==0 mkdir(dest_folder); end if size(up_img,3)>1 colored=1; else colored=0; end display('Extracting depth edges...'); %convert images to grayscale if colored==1 gu=double(rgb2gray(up_img)); gr=double(rgb2gray(right_img)); gd=double(rgb2gray(down_img)); gl=double(rgb2gray(left_img)); else gu=double(up_img); gr=double(right_img); gd=double(down_img); gl=double(left_img); end %remove specular regions [gu,gr,gd,gl]=removeSpecRegions(gu,gr,gd,gl); %get max image I_max=max(max(gu,gr),max(gd,gl)); %compute ratio images ru=(gu+1)./(I_max+1); rr=(gr+1)./(I_max+1); rd=(gd-+1)./(I_max+1); rl=(gl+1)./(I_max+1); %detect edges fx = fspecial('Prewitt'); %try 'Prewitt' fy = fx'; edu = imfilter(ru,fx); edr = imfilter(rr,fy); edd = imfilter(rd,fx); edl = imfilter(rl,fy); %calculate edge transitions edu = edu.*(edu>0); %keep only first negative transition (going from top to bottom) edr = abs(edr.*(edr<0)); %keep only second negative transition (going from left to right) edd = abs(edd.*(edd<0)); %keep only second negative transition (going from top to bottom) edl = edl.*(edl>0); %keep only first negative transition (going from left to right) mask_all=max(max(edu,edr),max(edd,edl)); %combine all edges together %remove dots from mask_all % % %(skip it (line 87-91) in the person case, gives more better results) %clean filters se = offsetstrel('ball',2,2); ero=imerode(mask_all,se); %erode the mask to remove small objectgs ero=mat2gray(ero); %normalize it mask_all=mask_all.*(bwareaopen(ero>0.1,50,8)); %remove small dots (again) mask_all=medfilt2(mask_all,[3,3]); %third level of filtering edges=(mask_all)>0.25; %convert to bw %show images %original images figure('units','normalized','outerposition',[0 0 1 1]) %full screen subplot(2,2,1); imshow(up_img); title('Up image'); subplot(2,2,2); imshow(right_img); title('Right image'); subplot(2,2,3); imshow(down_img); title('Down image'); subplot(2,2,4); imshow(left_img); title('Left image'); axes('Position',[0 0 1 1],'Xlim',[0 1],'Ylim',[0 1],'Box','off',... 'Visible','off','Units','normalized', 'clipping' , 'off'); %report squared reconstruction error t=text(0.5, 1,'Original images','HorizontalAlignment',... 'center','VerticalAlignment', 'top'); t.FontSize = 15; %edges %original images figure('units','normalized','outerposition',[0 0 1 1]) %full screen subplot(2,2,1); imshow(1-edu,[]); title('Up edges'); subplot(2,2,2); imshow(1-edr,[]); title('Right edges'); subplot(2,2,3); imshow(1-edd,[]); title('Down edges'); subplot(2,2,4); imshow(1-edl,[]); title('Left edges'); axes('Position',[0 0 1 1],'Xlim',[0 1],'Ylim',[0 1],'Box','off',... 'Visible','off','Units','normalized', 'clipping' , 'off'); %report squared reconstruction error t=text(0.5, 1,'Edges images','HorizontalAlignment',... 'center','VerticalAlignment', 'top'); t.FontSize = 15; %show mask all (before cleaning) figure; imshow(mask_all,[]); title('Max edges') %show final edge mask (after cleaning) figure; imshow(1-edges,[]); title('Depth edges') imwrite(1-edges,fullfile(dest_folder,'edge-mask.jpg')); %% NPR image display('Generating stylized images...'); a=0.3; lambda=double(edges); %make depth edges =1 lambda(mask_all<0.9 & mask_all>0.1)=a; %make texture edges = a lambda(lambda==0)=0.2; %values for featureless pixels lambda=reshape(lambda,size(edges)); %reshape it lambda=lambda+1.3*edges; %get colored target image without shadows if colored==1 % T=up_img; %initialize it with any one of input images T(:,:,1)=max(max(up_img(:,:,1),down_img(:,:,1)),max(left_img(:,:,1),... right_img(:,:,1))); T(:,:,2)=max(max(up_img(:,:,2),down_img(:,:,2)),max(left_img(:,:,2),... right_img(:,:,2))); T(:,:,3)=max(max(up_img(:,:,3),down_img(:,:,3)),max(left_img(:,:,3),... right_img(:,:,3))); else T=I_max; end %now apply poisson image editing using T (target image) M (mask) and L %(laplacian of source image). display('Applying Poisson image editing...'); Tt=imresize(T,[300,300]); %resize to speed up Poisson blending Ll=imresize(lambda,[300,300]); %resize to speed up Poisson blending stylized_img_=PIE(Tt,Ll,1-colored); %Poisson blending stylized_img_=imresize(stylized_img_,[size(T,1),size(T,2)]); %resize to original size stylized_img_=uint8(stylized_img_*255); %from double to uint8 stylized_img_=RGBHistMatch(stylized_img_,T); %histogram matching e=uint8(cat(3,edges,edges,edges)); %prepare edges to be added se = offsetstrel('ball',2,2); %change the thickness of edges edilate=imdilate(e,se); stylized_img=stylized_img_.*(1-edilate); figure; imshow(stylized_img); %show the final stylized image title('Synthetic image'); imwrite(stylized_img,fullfile(dest_folder,'stylized_imgB.jpg')); %save it %use white edges stylized_img=stylized_img_+(255*e); figure; imshow(stylized_img); %show the final stylized image title('Synthetic image'); imwrite(stylized_img,fullfile(dest_folder,'stylized_imgW.jpg')); %save it end